-module(tr_server).

-behaviour(gen_server).

-record(state, {port, lsock}).

-export([start_link/1,accept/1]).

-export([init/1,
         handle_cast/2,
         handle_info/2,
         terminate/2]).

start_link(Port) ->
    gen_server:start_link(?MODULE, [Port], []).

init([Port]) ->
    gen_server:cast(self(), {listen, Port}),
    {ok, #state{port=Port}}.

handle_cast({listen,Port}, State) ->
    {ok, LSock} = gen_tcp:listen(Port, [{active,once}]),
    {ok, Socket} = gen_tcp:accept(LSock),
    AcceptPid = spawn(?MODULE, accept, [Socket]),
    inet:tcp_controlling_process(Socket, AcceptPid),
    gen_server:cast(self(), {listen,Port}),
    {noreply, State};

handle_cast(stop, State) ->
    {noreply, State}.

handle_info({tcp, _Port, RawData}, State) ->
    io:format("~p~n", [RawData]),
    inet:setopts(State#state.lsock, [{active, once}]),
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

accept(Socket) ->
    receive 
        {tcp, _Port, RawData} ->
            io:format("~p~n", [RawData]),
            inet:setopts(Socket, [{active, once}])
    end,
    accept(Socket).
